package org.zjx.analyse;

import org.zjx.common.entity.ParagraphBean;
import org.zjx.common.entity.Rect;
import org.zjx.resolution.IScreenResolution;
import org.zjx.resolution.ResolutionAttributes;
import org.zjx.resolution.ResolutionButton;
import org.zjx.util.ImageUtil;
import org.zjx.window.GameWindow;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public abstract class AbstractAction {
    protected GameWindow gameWindow;
    protected IScreenResolution resolution;
    protected final ScreenshotAnalyse screenshotAnalyse;

    protected Rect windowArea; //子窗口相对位置 ，没有子窗口就是游戏界面

    public AbstractAction(IScreenResolution resolution, ScreenshotAnalyse screenshotAnalyse) {
        this.resolution = resolution;
        resolution.loadResolution();
        this.screenshotAnalyse = screenshotAnalyse;
        this.gameWindow = screenshotAnalyse.getGameWindow();
        if (resolution.getOriginBounds() != null) {
            this.windowArea = resolution.getOriginBounds(); //赋予子窗口初始区域
        }else {
            windowArea = gameWindow.getMockBounds(); //赋予游戏界面大小
        }
    }

    public void reSetAction(IScreenResolution resolution){
        this.resolution = resolution;
        resolution.loadResolution();
        if (resolution.getOriginBounds() != null) {
            this.windowArea = resolution.getOriginBounds(); //赋予子窗口初始区域
        }else {
            windowArea = gameWindow.getMockBounds(); //赋予游戏界面大小
        }
    }

    //============================================================================================================================================================

    //窗口是否在原位未移动过
    public boolean inSituLocation() {
        return screenshotAnalyse.haveResolutionButton(windowArea,new ResolutionButton(resolution.getRefImageArea(),resolution.getRefImage()));
    }

    public void restore(){
        Rect rect = findReferenceImageWithRetry(ImageUtil.stringToBufferedImage(resolution.getRefImage()));
        Rect handoff = screenshotAnalyse.conversion(resolution.getOriginBounds(),resolution.getRefImageArea());
        gameWindow.dragMouse(rect.getCenter().x,rect.getCenter().y,handoff.getCenter().x,handoff.getCenter().y);
    }

    // 带重试机制的参考图片查找
    public Rect findReferenceImageWithRetry(BufferedImage refImage) {
        Rect window = gameWindow.getMockBounds();

        Queue<Point> pointQueue = new LinkedList<>();
        pointQueue.add(new Point(100, 100));
        pointQueue.add(new Point(100, window.getBottom() - 100));
        pointQueue.add(new Point(window.getRight() - 100, 100));
        pointQueue.add(new Point(window.getRight() - 100, window.getBottom() - 100));

        do {
            List<Point> points = ImageUtil.matchTemplate(gameWindow.getScreenshot(), refImage);
            if (!points.isEmpty()) {
                return new Rect(points.get(0).x, points.get(0).y, points.get(0).x + refImage.getWidth() - 1, points.get(0).y + refImage.getHeight() - 1);
            }
            Point qPoint = pointQueue.poll();
            assert qPoint != null;
            gameWindow.getGameOperate().moveMouse(qPoint.x, qPoint.y);
            gameWindow.delay(30);
            gameWindow.flush();
        } while (!pointQueue.isEmpty());
        return null;
    }


    //============================================================================================================================================================

    public boolean clickButton(String buttonName) {
        ResolutionButton button = resolution.getButton(buttonName);
        if (button == null) throw new RuntimeException("按钮不存在!!!");
        return screenshotAnalyse.clickResolutionButton(windowArea, button);
    }

    public String getIdentifyString(String attributeName) {
        ResolutionAttributes attributes = resolution.getAttribute(attributeName);
        if (attributes == null) throw new RuntimeException("属性不存在!!!");
        return screenshotAnalyse.identifyString(windowArea, attributes);
    }

    public List<ParagraphBean.Word> getIdentify(String attributeName) {
        ResolutionAttributes attributes = resolution.getAttribute(attributeName);
        if (attributes == null) throw new RuntimeException("属性不存在!!!");
        return screenshotAnalyse.identify(windowArea, attributes);
    }

    public boolean haveButton(String buttonName) {
        ResolutionButton button = resolution.getButton(buttonName);
        if (button == null) throw new RuntimeException("按钮不存在!!!");
        return screenshotAnalyse.haveResolutionButton(windowArea, button);
    }

    public boolean haveColors(Rect rect, List<Color> colors) {
        return screenshotAnalyse.haveColors(windowArea, rect, colors);
    }

    public void flushScreenshot() {
        gameWindow.flush();
    }
}
